package com.harmontronics.hanma.paas.paas.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.harmontronics.hanma.paas.paas.common.MosResponse;
import com.harmontronics.hanma.paas.paas.consts.NumberEnum;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.GroupMemberUser;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.HmUserGroupMember;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.MemberOrg;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.valueobject.HmUserGroupMemberFields;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.mapper.HmUserGroupMemberMapper;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmUserGroupMemberRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupMemberPO;
import com.harmontronics.hanma.paas.paas.domain.iam.service.HmUserGroupMemberService;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.SsoOrgResult;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.SsoOrgTreeDtoResult;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.SsoUserDtoResult;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.valueobject.Constants;
import com.harmontronics.hanma.paas.paas.domain.organization.repository.po.HmOrgPO;
import com.harmontronics.hanma.paas.paas.domain.organization.service.MosService;
import com.harmontronics.hanma.paas.paas.exception.ErrorKeyException;
import com.harmontronics.hanma.paas.paas.utils.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

@Service("hmUserGroupMemberMosService")
@DS("#header.App-Unique")
@ConditionalOnProperty(prefix = "mos.oss",name="enabled",havingValue = "true")
public class HmUserGroupMemberMosService extends HmUserGroupMemberService implements
        IHmUserGroupMemberService {
    @Autowired
    private HmUserGroupMemberRepository hmUserGroupMemberRepository;

    @Autowired
    private HmUserGroupMemberMapper hmUserGroupMemberMapper;

    @Autowired
    private IHmUserGroupManageService hmUserGroupManageService;

    @Autowired
    private MosService mosService;

    @Override
    public List<GroupMemberUser> selectGroupMemberWithGroupId(Long groupId){

        List<GroupMemberUser> memberUserList = new ArrayList<>();
        QueryWrapper<HmUserGroupMemberPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(HmUserGroupMemberFields.USER_GROUP_ID,groupId);
        List<HmUserGroupMemberPO> groupMemberPOList = hmUserGroupMemberRepository.list(queryWrapper);
        List<Long> userIdList = groupMemberPOList.stream()
                .filter(m -> m.getIsOrg() == 0)
                .map(m -> m.getUnionId())
                .collect(Collectors.toList());
        List<Long> orgIdList = groupMemberPOList.stream()
                .filter(m -> m.getIsOrg() == 1)
                .map(m -> m.getUnionId())
                .collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(userIdList)){
            String tmpIds = userIdList.stream().map(id -> id.toString())
                    .collect(Collectors.joining(","));
            MosResponse<List<SsoUserDtoResult>> response = mosService.listByIds(tmpIds);
            if(response.isOk()){
                List<SsoUserDtoResult> userDtoResultList = response.getData();
                if(CollectionUtils.isNotEmpty(userDtoResultList)){
                    for(SsoUserDtoResult userDtoResult : userDtoResultList){
                        Long userId = userDtoResult.getId();
                        String username = userDtoResult.getUsername();
                        GroupMemberUser groupMemberUser = new GroupMemberUser();
                        if(StringUtils.isNotBlank(username)){
                            username = userDtoResult.getName();
                        }
                        groupMemberUser.setId(groupId)
                                .setName(username).setIsOrg(NumberEnum.ZERO.getNum())
                                .setUnionId(userId);
                        memberUserList.add(groupMemberUser);
                    }
                }
            }
        }
        if(CollectionUtils.isNotEmpty(orgIdList)){
            String tmpOrgIds = orgIdList.stream().map(id -> id.toString())
                    .collect(Collectors.joining(","));
            List<SsoOrgResult> orgResultList = mosService.getOrgByOrgIds(tmpOrgIds);
            if(CollectionUtils.isNotEmpty(orgResultList)){
                for(SsoOrgResult orgResult : orgResultList){
                    Long orgId = orgResult.getId();
                    String orgName = orgResult.getName();
                    GroupMemberUser groupMemberUser = new GroupMemberUser();
                    groupMemberUser.setId(groupId).setIsOrg(NumberEnum.ONE.getNum())
                            .setUnionId(orgId).setName(orgName);
                    memberUserList.add(groupMemberUser);
                }
            }
        }
        return memberUserList;
    }

    @Override
    public void create(List<HmUserGroupMember> userGroupMemberList) {
        List<HmUserGroupMember> tmpOrgMemberList =  new ArrayList<>();
        List<HmUserGroupMember> tmpUserGroupMemberCreateList = new ArrayList<>();
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(userGroupMemberList)) {
            Long userGroupId = userGroupMemberList.get(0).getUserGroupId();
            //要创建的部门
            List<HmUserGroupMember> insertOrgMemberList = userGroupMemberList.stream().
                    filter(member-> member.getIsOrg() == NumberEnum.ONE.getNum())
                    .collect(Collectors.toList());
            //要创建的人员
            List<HmUserGroupMember> insertUserMemberList = userGroupMemberList.stream().
                    filter(member-> member.getIsOrg() == NumberEnum.ZERO.getNum())
                    .collect(Collectors.toList());
            //过滤已经存在的部门
            if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(insertOrgMemberList)){
                //获取已经存在的部门
                List<HmUserGroupMember> existOrgMemberList = super.getOrgMember(userGroupId);
                //查询当前用户组用户的所属部门
                List<MemberOrg> memberOrgList  = getOrgInfoByGroupId(userGroupId);
                for (HmUserGroupMember insertOrgMember: insertOrgMemberList ) {
                    //判断插入的部门是否已存在
                    if(!existOrgMemberList.contains(insertOrgMember)){
                        tmpOrgMemberList.add(insertOrgMember);
                    }
                    //如果已创建的人员在新添加的部门中，则删除
                    if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(memberOrgList)){
                        List<Long> removeIdList = new ArrayList<>();
                        for (MemberOrg memberOrg : memberOrgList) {
                            if(memberOrg.getParentIds() != null){
                                if(memberOrg.getOrgId().longValue() == insertOrgMember.getUnionId() ||
                                        memberOrg.getParentIds().contains(insertOrgMember.getUnionId().toString())){
                                    removeIdList.add(memberOrg.getId());
                                }
                            }
                        }
                        super.removeByIds(removeIdList);
                    }
                }
            }

            if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(tmpOrgMemberList)){
                tmpUserGroupMemberCreateList.addAll(tmpOrgMemberList);
            }
            tmpUserGroupMemberCreateList.addAll(insertUserMemberList);



            // 按照 isOrg进行降序排序，先插入组织架构，再写入人员
            tmpUserGroupMemberCreateList.sort((o1, o2) -> o2.getIsOrg().compareTo(o1.getIsOrg()));
            List<ErrorKeyException> exceptionList = new ArrayList<>();
            for (HmUserGroupMember userGroupMemberCreate : tmpUserGroupMemberCreateList) {
                try {
                    insertSingleMember(userGroupMemberCreate);
                } catch (ErrorKeyException exception) {
                    exceptionList.add(exception);
                }
            }

            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(exceptionList)) {
                if(exceptionList.size() == tmpUserGroupMemberCreateList.size()){
                    throw exceptionList.get(0);
                }
            }
        }
    }

    private void insertSingleMember(HmUserGroupMember userGroupMemberCreate) {
        boolean isNotInGroupMember = true;
        if (NumberEnum.ZERO.getNum() == userGroupMemberCreate.getIsOrg()) {
            // 如果当前人所在的部门已经存在，则直接跳过
            List<HmUserGroupMemberPO> groupMemberList = getUserGroupMemberByUserId(
                            userGroupMemberCreate.getUserGroupId(), userGroupMemberCreate.getUnionId());
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(groupMemberList)) {
                isNotInGroupMember = false;
            }

            if(isNotInGroupMember){
                MosResponse<List<SsoOrgTreeDtoResult>> response = mosService.getOrgByUserId(userGroupMemberCreate.getUnionId());
                if(response.isOk()){
                    List<SsoOrgTreeDtoResult> orgPoList = response.getData();
                    for (int i = 0; i < orgPoList.size(); i++) {
                        SsoOrgTreeDtoResult po = orgPoList.get(i);
                        String tmpIds = po.getParentIds();
                        if( StringUtil.isNotBlank(tmpIds)){
                            String[] parentsIds = tmpIds.replace(Constants.LEFT_SQUARE_BRACKETS,"").split(Constants.RIGHT_SQUARE_BRACKETS);
                            List<Long> parentIdList = Arrays.stream(parentsIds).map(id -> Long.parseLong(id)).collect(Collectors.toList());
                            for (int j = 0; j < parentIdList.size(); j++) {
                                Long parentId = parentIdList.get(j);
                                QueryWrapper<HmUserGroupMemberPO> queryWrapper = new QueryWrapper<>();
                                queryWrapper
                                        .eq(HmUserGroupMemberFields.USER_GROUP_ID, userGroupMemberCreate.getUserGroupId())
                                        .eq(HmUserGroupMemberFields.UNION_ID, parentId)
                                        .eq(HmUserGroupMemberFields.IS_ORG, NumberEnum.ONE.getNum());
                                List<HmUserGroupMemberPO> groupMemberPOList =
                                        super.getMemberWithUnionId(userGroupMemberCreate.getUserGroupId(),parentId);
                                if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(groupMemberPOList)) {
                                    isNotInGroupMember = false;
                                    break;
                                }
                            }
                        }else{
                            Long orgId = po.getId();
                            List<HmUserGroupMemberPO> groupMemberPOList = super.getMemberWithUnionId(userGroupMemberCreate.getUserGroupId(),orgId);
                            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(groupMemberPOList)) {
                                isNotInGroupMember = false;
                                break;
                            }
                        }

                    }
                }
            }
        }

        if (isNotInGroupMember) {
            /**
             * 如果一个用户是父用户组的管理员，则无法再添加为子用户组的管理员或成员，添加是给出提示"该用户已经拥有该用户组的管理权限"
             * 如果一个用户是子用户组的管理员或成员，则无法再添加为父用户的管理员，添加是给出提示"该用户已经是该子用户组的管理员或成员"
             */
            if (userGroupMemberCreate.getIsOrg().equals(NumberEnum.ZERO.getNum())) {
                // 如果是管理员则不能添加为组员给出提示“该用户已经是管理员，无法再添加为组员”
                super.checkCurrentIsManage(
                        userGroupMemberCreate.getUnionId(), userGroupMemberCreate.getUserGroupId());

                hmUserGroupManageService.checkUser(
                        userGroupMemberCreate.getUnionId(), userGroupMemberCreate.getUserGroupId());
            }

            HmUserGroupMemberPO userGroupMember =
                    new HmUserGroupMemberPO()
                            .setDeleted(Integer.valueOf(0))
                            .setUserGroupId(userGroupMemberCreate.getUserGroupId())
                            .setUnionId(userGroupMemberCreate.getUnionId())
                            .setIsOrg(userGroupMemberCreate.getIsOrg());
            hmUserGroupMemberMapper.insert(userGroupMember);
        }
    }

    private List<MemberOrg> getOrgInfoByGroupId(Long groupId){
        List<MemberOrg> memberOrgList = new ArrayList<>();
        QueryWrapper<HmUserGroupMemberPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(HmUserGroupMemberFields.USER_GROUP_ID,groupId)
                .eq(HmUserGroupMemberFields.IS_ORG,NumberEnum.ONE.getNum());
        List<HmUserGroupMemberPO> groupMemberPOList = hmUserGroupMemberRepository.list(queryWrapper);
        List<Long> orgIdList = groupMemberPOList.stream().map(member -> member.getUnionId())
                .collect(Collectors.toList());
        String tmpOrgIds = orgIdList.stream()
                .map(id -> id.toString()).collect(Collectors.joining(","));
        List<SsoOrgResult> orgResultList = mosService.getOrgByOrgIds(tmpOrgIds);
        if(CollectionUtils.isNotEmpty(orgResultList)){
            for(SsoOrgResult orgResult : orgResultList){
                MemberOrg memberOrg = new MemberOrg();
                Long orgId = orgResult.getId();
                String parentIds = memberOrg.getParentIds();
                memberOrg.setOrgId(orgId).setParentIds(parentIds);
                memberOrgList.add(memberOrg);

            }
        }
        return memberOrgList;
    }

    private List<HmUserGroupMemberPO> getUserGroupMemberByUserId(Long userGroupId,Long userId){
        List<HmUserGroupMemberPO> groupMemberPOList = new ArrayList<>();
        MosResponse<List<SsoOrgTreeDtoResult>> response = mosService.getOrgByUserId(userId);
        if(response.isOk()){
            List<SsoOrgTreeDtoResult> orgTreeDtoResultList = response.getData();
            if(CollectionUtils.isNotEmpty(orgTreeDtoResultList)){
                List<Long> orgIdList = orgTreeDtoResultList.stream().map(org -> org.getId())
                        .collect(Collectors.toList());
                QueryWrapper<HmUserGroupMemberPO> queryWrapper = new QueryWrapper<>();
                queryWrapper.in(HmUserGroupMemberFields.UNION_ID,orgIdList)
                        .eq(HmUserGroupMemberFields.USER_GROUP_ID,userGroupId)
                        .eq(HmUserGroupMemberFields.IS_ORG,NumberEnum.ONE.getNum());
                groupMemberPOList = hmUserGroupMemberRepository.list(queryWrapper);
            }
        }
        return groupMemberPOList;
    }

}
